package com.syezon.wifikey.news.viewmodel;

import android.app.Application;
import android.arch.lifecycle.AndroidViewModel;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.LogUtils;
import com.bytedance.sdk.openadsdk.AdSlot;
import com.bytedance.sdk.openadsdk.TTAdNative;
import com.bytedance.sdk.openadsdk.TTNativeExpressAd;
import com.hodanet.appadvplatclient.AdvClient;
import com.hodanet.appadvplatclient.ReportAgent;
import com.hodanet.appadvplatclient.ad.AdInfo;
import com.hodanet.appadvplatclient.api.BaseResult;

import com.qq.e.ads.nativ.ADSize;
import com.qq.e.ads.nativ.NativeExpressAD;
import com.qq.e.ads.nativ.NativeExpressADView;
import com.qq.e.comm.util.AdError;
import com.syezon.wifikey.ad.AdPositionEnum;
import com.syezon.wifikey.ad.CommonAdConfig;
import com.syezon.wifikey.ad.ConfigService;
import com.syezon.wifikey.api.ApiClient;
import com.syezon.wifikey.channel.ChannelConfig;
import com.syezon.wifikey.config.GDTConfig;
import com.syezon.wifikey.config.TTAdManagerHolder;
import com.syezon.wifikey.news.info.YiYouLiaoNewsInfoBean;
import com.syezon.wifikey.news.info.YiYouLiaoNewsListBean;
import com.syezon.wifikey.splash.config.SplashConfig;
import com.syezon.wifikey.utils.Utils;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Function;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;

public class YiYouLiaoNewsListViewModel extends AndroidViewModel {
    private MutableLiveData<List<YiYouLiaoNewsInfoBean>> refreshMutableLiveData = new MutableLiveData<>();
    private MutableLiveData<List<YiYouLiaoNewsInfoBean>> loadMoreMutableLiveData = new MutableLiveData<>();
    //需要多少条广告   广告请求条数= 每页请求数量/每隔N条请求一次广告
    private int requestNumOfAd;
    private final CommonAdConfig commonAdConfig;

    public YiYouLiaoNewsListViewModel(@NonNull Application application) {
        super(application);
        commonAdConfig = new CommonAdConfig("yiyouliao");
        requestNumOfAd = REQUEST_COUNT / SplashConfig.getYiYouLiaoNewsAdCount();
    }


    public static final int EVENT_LOADMORE = 0;
    public static final int EVENT_REFRESH = 1;
    public static final int EVENT_FIRST_LOAD = 2;
    private static final int REQUEST_COUNT = 20;

    public MutableLiveData<List<YiYouLiaoNewsInfoBean>> getLoadMoreMutableLiveData() {
        return loadMoreMutableLiveData;
    }

    public MutableLiveData<List<YiYouLiaoNewsInfoBean>> getRefreshMutableLiveData() {
        return refreshMutableLiveData;
    }


    public void onRefresh(int group, String channelTag) {
        Observable<BaseResult<List<AdInfo>>> optResultAd2 = Observable.create(new ObservableOnSubscribe<BaseResult<List<AdInfo>>>() {
            @Override
            public void subscribe(ObservableEmitter<BaseResult<List<AdInfo>>> e) throws Exception {
                BaseResult<List<AdInfo>> advs = AdvClient.getInstance().getNewAdvs(AdPositionEnum.WANGYI_NEWS.getPosId(), ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                e.onNext(advs);
            }
        });

        Observable<String> observable = ApiClient.queryYiyouNewsList(REQUEST_COUNT, group, channelTag);
        Observable.zip(observable, optResultAd2, new BiFunction<String, BaseResult<List<AdInfo>>, List<YiYouLiaoNewsInfoBean>>() {
            @Override
            public List<YiYouLiaoNewsInfoBean> apply(String s, BaseResult<List<AdInfo>> listBaseResult) throws Exception {
                commonAdConfig.setAdList(listBaseResult.getData());
                return parseModel(s);
            }
        }).map(new Function<List<YiYouLiaoNewsInfoBean>, List<YiYouLiaoNewsInfoBean>>() {
            @Override
            public List<YiYouLiaoNewsInfoBean> apply(List<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans) throws Exception {
                List<Object> ttNativeExpressAds = loadNewsAd();
                return insertAllAds(ttNativeExpressAds, yiYouLiaoNewsInfoBeans);
            }
        }).subscribeOn(Schedulers.io())
                .subscribe(new Observer<List<YiYouLiaoNewsInfoBean>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(List<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans) {
                        refreshMutableLiveData.postValue(yiYouLiaoNewsInfoBeans);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    public void loadMore(String channelTag) {
        ApiClient.queryYiyouNewsList(REQUEST_COUNT, EVENT_LOADMORE, channelTag)
                .subscribeOn(Schedulers.io())
                .map(new Function<String, List<YiYouLiaoNewsInfoBean>>() {
                    @Override
                    public List<YiYouLiaoNewsInfoBean> apply(String s) throws Exception {
                        return parseModel(s);
                    }
                })
                .map(new Function<List<YiYouLiaoNewsInfoBean>, List<YiYouLiaoNewsInfoBean>>() {
                    @Override
                    public List<YiYouLiaoNewsInfoBean> apply(List<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans) throws Exception {
                        List<Object> ttNativeExpressAds = loadNewsAd();
                        return insertAllAds(ttNativeExpressAds, yiYouLiaoNewsInfoBeans);
                    }
                })
                .subscribe(new DisposableObserver<List<YiYouLiaoNewsInfoBean>>() {
                    @Override
                    public void onNext(List<YiYouLiaoNewsInfoBean> s) {
                        loadMoreMutableLiveData.postValue(s);
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        LogUtils.e(e.getMessage());
                        loadMoreMutableLiveData.postValue(null);
                    }

                    @Override
                    public void onComplete() {
                    }
                });
    }

    private ArrayList<YiYouLiaoNewsInfoBean> parseModel(String data) {
        YiYouLiaoNewsListBean result = new YiYouLiaoNewsListBean();
        YiYouLiaoNewsListBean.DataBean dataBean = new YiYouLiaoNewsListBean.DataBean();
        result.setData(dataBean);
        ArrayList<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans = new ArrayList<>();
        try {
            JSONObject adJson = new JSONObject(data);
            int rc = adJson.optInt("rc", 0);
            int msg = adJson.optInt("msg", 0);
            JSONObject dataJson = adJson.optJSONObject("data");
            JSONArray infosJson = dataJson.optJSONArray("infos");
            for (int i = 0; infosJson != null && i < infosJson.length(); ++i) {
                JSONObject adItemJson = infosJson.optJSONObject(i);
                YiYouLiaoNewsListBean.DataBean.InfosBean infosBean = new YiYouLiaoNewsListBean.DataBean.InfosBean();
                infosBean.setOriginalPublishTime(adItemJson.optString("originalPublishTime"));
                infosBean.setH5DetailLink(adItemJson.optString("h5DetailLink"));
                infosBean.setInfoType(adItemJson.optString("infoType"));
                infosBean.setTitle(adItemJson.optString("title"));
                JSONArray imgsJson = adItemJson.optJSONArray("thumbnails");
                ArrayList<YiYouLiaoNewsListBean.DataBean.InfosBean.ImgsBean> imgs = new ArrayList<>();
                infosBean.setImgs(imgs);
                for (int i1 = 0; i1 < imgsJson.length(); i1++) {
                    JSONObject imgJson = imgsJson.optJSONObject(i1);
                    YiYouLiaoNewsListBean.DataBean.InfosBean.ImgsBean imgsBean = new YiYouLiaoNewsListBean.DataBean.InfosBean.ImgsBean();
                    imgsBean.setHeight(imgJson.optInt("height", 0));
                    imgsBean.setWidth(imgJson.optInt("width", 0));
                    imgsBean.setUrl(imgJson.optString("url"));
                    imgs.add(imgsBean);
                }
                infosBean.setPublishTime(adItemJson.optString("publishTime"));
                infosBean.setChannelTag(adItemJson.optString("channelTag"));
                infosBean.setCategory(adItemJson.optString("category"));
                infosBean.setSource(adItemJson.optString("source"));
                int imgType = adItemJson.optInt("imgType");
                infosBean.setImgType(imgType);
                YiYouLiaoNewsInfoBean yiYouLiaoNewsInfoBean = new YiYouLiaoNewsInfoBean();
                yiYouLiaoNewsInfoBean.setInfosBean(infosBean);
                yiYouLiaoNewsInfoBean.setType(imgType);
                yiYouLiaoNewsInfoBeans.add(yiYouLiaoNewsInfoBean);
            }
        } catch (Exception e) {
            return yiYouLiaoNewsInfoBeans;
        }
        return yiYouLiaoNewsInfoBeans;
    }


    private List<Object> loadNewsAd() {
        //step4:创建广告请求参数AdSlot,具体参数含义参考文档
        final List<Object> adsList = new ArrayList<>();
        try {
            //循环计数
            int time = 0;
            LogUtils.e("requestNumOfAd      " + requestNumOfAd);
            while (adsList.size() < requestNumOfAd && time < requestNumOfAd) {
                final AdInfo nextAdSource = commonAdConfig.getNextAdSource();
                switch (nextAdSource.getType()) {
                    case AdInfo.AD_TYPE_CHUAN_SHAN_JIA:
                        LogUtils.e("易有料 穿山甲");
                        break;
                    case AdInfo.AD_TYPE_GUANG_DIAN_TONG:
                        LogUtils.e("易有料 广点通");
                        break;
                    default:
                        LogUtils.e("易有料 自有");
                        break;
                }
                final CountDownLatch countDownLatch = new CountDownLatch(1);
                if (nextAdSource.getType() == AdInfo.AD_TYPE_CHUAN_SHAN_JIA) {
                    AdSlot adSlot = new AdSlot.Builder()
                            .setCodeId(TTAdManagerHolder.YI_YOU_LIAO_NEWS)
                            .setSupportDeepLink(true)
                            .setExpressViewAcceptedSize(640, 0)
                            //请求广告数量为1到3条 最多3条
                            .setAdCount(1)
                            .build();
                    TTAdManagerHolder.get().createAdNative(Utils.getApp()).loadNativeExpressAd(adSlot, new TTAdNative.NativeExpressAdListener() {
                        @Override
                        public void onError(int i, String s) {
                            countDownLatch.countDown();
//                            commonAdConfig.saveLastShowAd(nextAdSource);
                            ReportAgent.reportAdvSdkFailed(nextAdSource, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                        }

                        @Override
                        public void onNativeExpressAdLoad(List<TTNativeExpressAd> ads) {
                            countDownLatch.countDown();
//                            commonAdConfig.saveLastShowAd(nextAdSource);
                            adsList.addAll(ads);
                            ReportAgent.reportAdvExtShow(nextAdSource, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                        }
                    });
                } else if (nextAdSource.getType() == AdInfo.AD_TYPE_GUANG_DIAN_TONG) {
                    ADSize adSize = new ADSize(ADSize.FULL_WIDTH, ADSize.AUTO_HEIGHT); // 消息流中用AUTO_HEIGHT
                    NativeExpressAD mAdManager = new NativeExpressAD(Utils.getApp(), adSize, GDTConfig.APP_ID, nextAdSource.getCode(), new NativeExpressAD.NativeExpressADListener() {
                        @Override
                        public void onADLoaded(List<NativeExpressADView> list) {
                            LogUtils.e("onADLoaded");
                            countDownLatch.countDown();
//                            commonAdConfig.saveLastShowAd(nextAdSource);
                            adsList.addAll(list);
                            ReportAgent.reportAdvExtShow(nextAdSource, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                        }

                        @Override
                        public void onRenderFail(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onRenderFail");
                        }

                        @Override
                        public void onRenderSuccess(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onRenderSuccess");
                        }

                        @Override
                        public void onADExposure(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADExposure");
                        }

                        @Override
                        public void onADClicked(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADClicked");
                            ReportAgent.reportAdvClick(nextAdSource, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                        }

                        @Override
                        public void onADClosed(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADClosed");
                        }

                        @Override
                        public void onADLeftApplication(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADLeftApplication");
                        }

                        @Override
                        public void onADOpenOverlay(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADOpenOverlay");
                        }

                        @Override
                        public void onADCloseOverlay(NativeExpressADView nativeExpressADView) {
                            LogUtils.e("onADCloseOverlay");
                        }

                        @Override
                        public void onNoAD(AdError adError) {
                            countDownLatch.countDown();
                            ReportAgent.reportAdvSdkFailed(nextAdSource, ChannelConfig.getChannel(), AppUtils.getAppVersionCode());
                        }
                    });
                    mAdManager.loadAD(1);
                } else {
                    countDownLatch.countDown();
                    adsList.add(nextAdSource);
//                    commonAdConfig.saveLastShowAd(nextAdSource);
                }
                commonAdConfig.saveLastShowAd(nextAdSource);
                time += 1;
                countDownLatch.await(2, TimeUnit.SECONDS);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return adsList;
    }

    private List<YiYouLiaoNewsInfoBean> insertAllAds(List<Object> ads, List<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans) {
        boolean showYiYouLiaoNewsAd = ConfigService.getInstance().isShowYiyouLiaoNewsAd();
        if (!showYiYouLiaoNewsAd) {
            return yiYouLiaoNewsInfoBeans;
        }
        int interval = ads.size();
        if (interval > 0) {
            int yiYouLiaoNewsAdCount = SplashConfig.getYiYouLiaoNewsAdCount();
            for (int i = 0; i < ads.size(); i++) {
                int insertIndex = yiYouLiaoNewsAdCount * (i + 1) + i;
                if (insertIndex <= yiYouLiaoNewsInfoBeans.size()) {
                    YiYouLiaoNewsInfoBean yiYouLiaoNewsInfoBean = new YiYouLiaoNewsInfoBean();
                    Object o = ads.get(i);
                    if (o instanceof TTNativeExpressAd) {
                        yiYouLiaoNewsInfoBean.setType(YiYouLiaoNewsInfoBean.TYPE_AD_CSJ);
                        yiYouLiaoNewsInfoBean.setTtNativeExpressAd((TTNativeExpressAd) o);
                        yiYouLiaoNewsInfoBeans.add(insertIndex, yiYouLiaoNewsInfoBean);
                    } else if (o instanceof AdInfo) {
                        yiYouLiaoNewsInfoBean.setType(YiYouLiaoNewsInfoBean.TYPE_AD_SELF);
                        yiYouLiaoNewsInfoBean.setAdInfo((AdInfo) o);
                        yiYouLiaoNewsInfoBeans.add(insertIndex, yiYouLiaoNewsInfoBean);
                    } else if (o instanceof NativeExpressADView) {
                        yiYouLiaoNewsInfoBean.setType(YiYouLiaoNewsInfoBean.TYPE_AD_GDT);
                        yiYouLiaoNewsInfoBean.setNativeExpressADView((NativeExpressADView) o);
                        yiYouLiaoNewsInfoBeans.add(insertIndex, yiYouLiaoNewsInfoBean);
                    }
                }
            }
        }
        return yiYouLiaoNewsInfoBeans;
    }

    private List<YiYouLiaoNewsInfoBean> insertAds(List<TTNativeExpressAd> ttNativeExpressAds, List<YiYouLiaoNewsInfoBean> yiYouLiaoNewsInfoBeans) {
        boolean showYiYouLiaoNewsAd = ConfigService.getInstance().isShowYiyouLiaoNewsAd();
        if (!showYiYouLiaoNewsAd) {
            return yiYouLiaoNewsInfoBeans;
        }
        int interval = ttNativeExpressAds.size();
        if (interval > 0) {
            int yiYouLiaoNewsAdCount = SplashConfig.getYiYouLiaoNewsAdCount();
            for (int i = 0; i < ttNativeExpressAds.size(); i++) {
                int insertIndex = yiYouLiaoNewsAdCount * (i + 1) + i;
                if (insertIndex <= yiYouLiaoNewsInfoBeans.size()) {
                    TTNativeExpressAd ttNativeExpressAd = ttNativeExpressAds.get(i);
                    YiYouLiaoNewsInfoBean yiYouLiaoNewsInfoBean = new YiYouLiaoNewsInfoBean();
                    yiYouLiaoNewsInfoBean.setType(YiYouLiaoNewsInfoBean.TYPE_AD_CSJ);
                    yiYouLiaoNewsInfoBean.setTtNativeExpressAd(ttNativeExpressAd);
                    yiYouLiaoNewsInfoBeans.add(insertIndex, yiYouLiaoNewsInfoBean);
                }
            }
        }
        return yiYouLiaoNewsInfoBeans;
    }
}
